package com.shield.framework.security.store.db;


import com.shield.framework.config.ShieldConstant;
import com.shield.framework.jpa.entity.ShieldToken;
import com.shield.framework.jpa.repository.ShieldTokenRepository;
import com.shield.framework.security.auth.AuthUser;
import com.shield.framework.security.token.ShieldTokenStore;
import com.shield.framework.vo.TokenVo;
import eu.bitwalker.useragentutils.UserAgent;
import lombok.RequiredArgsConstructor;
import net.dreamlu.mica.core.utils.*;
import net.dreamlu.mica.ip2region.core.Ip2regionSearcher;
import net.dreamlu.mica.ip2region.core.IpInfo;
import org.springframework.http.HttpHeaders;
import org.springframework.security.authentication.AuthenticationServiceException;

import javax.servlet.http.HttpServletRequest;
import java.time.Duration;
import java.time.LocalDateTime;

/**
 * @description:
 * @Author And
 */
@RequiredArgsConstructor
public class ShieldDbTokenStore implements ShieldTokenStore {

    private final ShieldTokenRepository shieldTokenRepository;
    private final Ip2regionSearcher searcher;

    @Override
    public TokenVo get(String token) {
        String key = DigestUtil.md5Hex(token);
        ShieldToken shieldToken = shieldTokenRepository.findByTokenKey(key).orElseThrow(() -> new AuthenticationServiceException("请求需携带认证信息"));
        if(LocalDateTime.now().isAfter(shieldToken.getExpireTime())) return null;
        return BeanUtil.copyProperties(shieldToken,TokenVo.class);
    }

    @Override
    public void save(HttpServletRequest request, AuthUser authUser, String token, Duration expireTime) {
        String key = DigestUtil.md5Hex(token);
        String ip = WebUtil.getIP(request);
        UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader(HttpHeaders.USER_AGENT));
        String browser = userAgent.getBrowser().getName();
        ShieldToken shieldToken =new ShieldToken();
        shieldToken.setUserName(authUser.getUsername());
        shieldToken.setNickName(authUser.getNickName());
        shieldToken.setBrowser(browser);
        shieldToken.setIp(ip);
        IpInfo ipInfo = searcher.memorySearch(ip);
        if (ipInfo != null) {
            shieldToken.setAddress(ipInfo.getAddress());
        }
        shieldToken.setTokenKey(key);
        // token 摘要，前6后8，中间4位占位符
        shieldToken.setSummary(DesensitizationUtil.sensitive(token, 8, 8, CharPool.DOT, 4));
        shieldToken.setLoginTime(LocalDateTime.now());
        shieldToken.setExpireTime(LocalDateTime.now().plus(expireTime));
        shieldTokenRepository.save(shieldToken);
    }
}
